package com.pilipili.serverapi.manageUser.service;


import com.pilipili.common.Exception.BusinessRuntimeException;
import com.pilipili.common.Exception.CommonErrorCode;
import com.pilipili.common.controller.PageCommResult;
import com.pilipili.common.service.AbstractService;
import com.pilipili.common.util.BeanUtils;
import com.pilipili.serverapi.ErrorCode;
import com.pilipili.serverapi.manageUser.dto.req.RoleWithIdDto;
import com.pilipili.serverapi.manageUser.dto.resp.RoleWithCreateTimeDto;
import com.pilipili.serverapi.manageUser.entity.Permission;
import com.pilipili.serverapi.manageUser.entity.Role;
import com.pilipili.serverapi.manageUser.repository.RoleRepository;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 角色管理Service
 *
 * @author chen.guosheng
 */
@Service
public class RoleService extends AbstractService<RoleRepository, Role, Long> {

    @Transactional(readOnly = true)
    public PageCommResult<RoleWithCreateTimeDto> search(String roleName, int currentPage, int pageCount) {
        Pageable page = new PageRequest(currentPage, pageCount, Sort.Direction.DESC, "createTime");
        List<Role> roles = this.repository.findByRoleNameStartingWith(roleName, page);
        List<RoleWithCreateTimeDto> roleDtos = new ArrayList<RoleWithCreateTimeDto>();
        roles.forEach(role -> roleDtos.add(new RoleWithCreateTimeDto(role.getRoleName(), role.getDescription(), role.getId(), role.getCreateTime().toString())));
        Long total = this.repository.countByRoleNameStartingWith(roleName);
        return PageCommResult.successPageResult(roleDtos, currentPage, pageCount, total);
    }

    /**
     * 批量删除角色
     *
     * @param roleIds
     */
    @Transactional
    public void batchDelete(List<Long> roleIds) {
        // 由于设定了多对多关系，因jpa会自动删除角色与权限的联系记录
        this.repository.deleteByIdIn(roleIds);
    }

    @Transactional
    @Override
    public <RoleWithIdDto> Role editAfterFind(Long id, RoleWithIdDto dto, CommonErrorCode errorCode){
        Role role = this.find(id, errorCode);
        BeanUtils.copyProperties(dto, role);
        role.setCreateTime(new Date());
        return this.repository.save(role);
    }

    @Transactional
    public void assignPermissions(Long roleId, List<Permission> permissions) {
        Optional<Role> roleOptional = this.repository.findById(roleId);
        if(roleOptional.isPresent()){
            Role role = roleOptional.get();
            role.getPermissions().clear();
            for(Permission permission : permissions){
                role.getPermissions().add(permission);
            }
            this.repository.save(role);
        }
        else {
            throw new BusinessRuntimeException(ErrorCode.ROLE_NOT_FOUND);
        }
    }



}
